class_name Player
extends Character


@onready var enemySlots: EnemySlots = $EnemySlots

## 受伤后的保护时间，此时间连续受击不会受伤
@export var duration_protect_hurt: float = 0.8
## 每次攻击后会持续一段时间允许连击，在持续时间内继续攻击会进入下一级攻击状态
@export var combo_attack_duration: float = 0.5

## 玩家重生的位置，相对于相机中心的偏移
@export var reborn_position_offset: Vector2


const STATE_IDLE := "idle"
const STATE_WALK := "walk"
const STATE_PUNCH := "punch"
const STATE_PUNCH_ALT := "punchalt"
const STATE_THROW := "throw"
const STATE_KICK := "kick"
const STATE_ROUNDKICK := "roundkick"
const STATE_TAKEOFF := "takeoff"
const STATE_JUMP := "jump"
const STATE_LAND := "land"
const STATE_JUMPKICK := "jumpkick"
const STATE_HURT := "hurt"
const STATE_KNOCKDOWN := "knockdown"
const STATE_FALL := "fall"
const STATE_GROUNDED := "grounded"
const STATE_DEATH := "death"
const STATE_PICKUP := "pickup"
const STATE_SHOOT := "shoot"
const STATE_DROP := "drop"

const ANIMATION_IDLE := "idle"
const ANIMATION_WALK := "walk"
const ANIMATION_PUNCH := "punch"
const ANIMATION_PUNCH_ALT := "punch_alt"
const ANIMATION_THROW := "throw"
const ANIMATION_KICK := "kick"
const ANIMATION_ROUNDKICK := "roundkick"
const ANIMATION_TAKEOFF := "takeoff"
const ANIMATION_JUMP := "jump"
const ANIMATION_LAND := "land"
const ANIMATION_JUMPKICK := "jumpkick"
const ANIMATION_HURT := "hurt"
const ANIMATION_HURT_AIR := "hurt_air"
const ANIMATION_HURT_KNOCKDOWN := "hurt_knockdown"
const ANIMATION_FALL := "fall"
const ANIMATION_GROUNDED := "grounded"
const ANIMATION_DEATH := "death"
const ANIMATION_PICKUP := "pickup"
const ANIMATION_SHOOT := "shoot"
const ANIMATION_DROP := "drop"


var inputManager: InputManager

# 连击的持续时间，到达0时连击中断
var __combo_attack_cache: float = 0.0
var __combo_attack_state: String
# 受伤保护的时间
var __protect_hurt_time: float = 0.0
# 伤害的来源方向，比如攻击源在角色的左侧，则此向量方向为右
var __damage_emit_direction: Vector2


func _init():
	inputManager = InputManager.new()



func _ready():
	super._ready()

	set_initial_node_state()
	set_current_health(max_health)

	damageEmitter.monitoring = false
	damageEmitter.area_entered.connect(on_emit_damage)
	damageReceiver.damage_received.connect(on_receive_damage)



func _process(delta: float):
	inputManager._process_input()
	flip_sprite()
	_check_combo_attack(delta)
	__protect_hurt_time -= delta



# 根据生成数据设置初始化状态
func set_initial_node_state():
	if spawn_entry_mode == Character.EntryMode.DROP:
		stateMachine.spawn_initial_node_state = STATE_DROP



func set_reborn_node_state():
	enemySlots.all_slots_disabled(false)

	if spawn_entry_mode == Character.EntryMode.DROP:
		stateMachine.transition_to(STATE_DROP)



func is_in_air() -> bool:
	return characterSprite.position.y < -1.0



func take_damage_emit_direction() -> Vector2:
	return __damage_emit_direction


# 设置当前生命值
func set_current_health(health: int):
	super.set_current_health(health)
	DamageManager.player_health_change.emit(current_health, max_health)



# 发送伤害
func on_emit_damage(receiver_area: Area2D):
	var damage_receiver: DamageReceiver = receiver_area as DamageReceiver
	if damage_receiver == null:
		return

	var current_state_name = stateMachine.current_node_state_name
	if current_state_name == STATE_PUNCH or current_state_name == STATE_PUNCH_ALT or current_state_name == STATE_KICK:
		damage_receiver.damage_received.emit(damage,
											receiver_area.global_position - damageEmitter.global_position,
											DamageReceiver.HitType.NORMAL)
		SoundPlayer.play(SoundManager.Sound.HIT1, true)
	elif current_state_name == STATE_ROUNDKICK:
		damage_receiver.damage_received.emit(damage_power,
											receiver_area.global_position - damageEmitter.global_position,
											DamageReceiver.HitType.POWER)
		SoundPlayer.play(SoundManager.Sound.HIT2, true)
		DamageManager.heavy_blow_receive.emit()		# 镜头抖动
	elif current_state_name == STATE_JUMPKICK:
		damage_receiver.damage_received.emit(damage_power,
											receiver_area.global_position - damageEmitter.global_position,
											DamageReceiver.HitType.KNOCK_DOWN)
		SoundPlayer.play(SoundManager.Sound.HIT2, true)


# 接收到伤害信号
func on_receive_damage(damage_value: int, emit_direction: Vector2, hitType: DamageReceiver.HitType):
	if __protect_hurt_time > 0.0:
		return
	__damage_emit_direction = emit_direction
	# 计算受伤
	set_current_health(current_health - damage_value)

	lost_knife()
	lost_gun()

	var current_state_name = stateMachine.current_node_state_name
	# 跳起或被击倒类型攻击时进入击倒状态
	if current_state_name == STATE_JUMP || current_state_name == STATE_JUMPKICK || hitType == DamageReceiver.HitType.KNOCK_DOWN:
		stateMachine.transition_to(STATE_KNOCKDOWN)
	else:
		stateMachine.transition_to(STATE_HURT)


# 检查连击
func _check_combo_attack(delta: float):
	__combo_attack_cache -= delta
	# 连击中断
	if __combo_attack_cache < 0.0:
		__combo_attack_state = ""


func next_combo_attack_state() -> String:
	match __combo_attack_state:
		STATE_PUNCH:
			__combo_attack_state = STATE_PUNCH_ALT
		STATE_PUNCH_ALT:
			__combo_attack_state = STATE_KICK
		STATE_KICK:
			__combo_attack_state = STATE_ROUNDKICK
		_:
			__combo_attack_state = STATE_PUNCH
	__combo_attack_cache = combo_attack_duration
	return __combo_attack_state
